from django.db import transaction

from backend.cews.models import Parts, StockItem, StockItemRelation, Log, RepairOrderPart
import json
import logging

logger = logging.getLogger(__name__)

def get_parts_from_parent(parent_serial_no, parent_stock_code):
    result = []
    parts = Parts.objects.filter(serial_no=parent_serial_no, stock_code=parent_stock_code).filter(deleted=False)

    for part in parts:
        if part.is_parent:
            part_dict = {}
            part_dict["serial_no"] = part.serial_no
            part_dict["car"] = part.car
            part_dict["last_status"] = part.last_status
            part_dict["last_check_in"] = part.last_check_in
            part_dict["last_check_out"] = part.last_check_out
            part_dict["sw_ver"] = part.sw_ver
            part_dict["hw_ver"] = part.hw_ver
            part_dict["id"] = part.id
            part_dict["description"] = part.description

            try:
                part_dict["stock_code"] = \
                    StockItem.objects.get(
                        stock_code=part.stock_code,
                        deleted=False
                    ).stock_code
            except Exception:
                part_dict["stock_code"] = ""

            # children
            part_dict["child"] = {} 

            try:
                ## get parent stock code
                stock_item_parent = StockItem.objects.get(
                    stock_code=part.stock_code,
                    deleted=False
                )
                
                stock_item_children = stock_item_parent.children
                child_stock_dict = {
                    sr.sequence: sr
                    for sr in stock_item_children
                }
                for stock_sequence in child_stock_dict:
                    if not part.children:
                        s = StockItem.objects.get(
                                pk=child_stock_dict[stock_sequence].child.id
                            )
                        part_dict["child"][
                                    stock_sequence
                                ] = {
                                    "sequence": stock_sequence,
                                    "stock_code": s.stock_code,
                                    "serial_no": "",
                                    "car": "",
                                    "description":s.description
                                }
                    for child_part in part.children:
                        if child_part.sequence == stock_sequence:
                            part_dict["child"][
                                    child_part.sequence
                                ] = {
                                    "sequence": stock_sequence,
                                    "serial_no": child_part.serial_no,
                                    "stock_code": child_part.stock_code,
                                    "car": child_part.car,
                                    "sw_ver": child_part.sw_ver,
                                    "hw_ver": child_part.hw_ver,
                                    "id": child_part.id,                            
                                    "last_status" : child_part.last_status,
                                    "last_check_in" : child_part.last_check_in,
                                    "last_check_out" : child_part.last_check_out,
                                    "description" : child_part.description
                                }
                            
                        if stock_sequence not in part_dict["child"]:
                            s = StockItem.objects.get(
                                pk=child_stock_dict[stock_sequence].child.id
                            )
                            part_dict["child"][
                                    stock_sequence
                                ] = {
                                    "sequence": stock_sequence,
                                    "stock_code": s.stock_code,
                                    "serial_no": "",
                                    "car": "",
                                    "description":s.description
                                }
                            

            except Exception as ex:
                print(ex)
        result.append(part_dict)
           
    """ print(result) """
    return result


def get_parts_from_car(car):
    result = []
    print(car)
    if car == '' or car == None:
        parts = Parts.objects.all().filter(parent_part__isnull=True).filter(deleted=False)
    else:
        parts = Parts.objects.filter(car=car, parent_part__isnull=True).filter(deleted=False)
    print(parts)
    for part in parts:
        if part.is_parent:
            part_dict = {}
            part_dict["serial_no"] = part.serial_no
            part_dict["car"] = part.car
            part_dict["sw_ver"] = part.sw_ver
            part_dict["hw_ver"] = part.hw_ver
            part_dict["id"] = part.id
            part_dict["description"] = part.description

            try:
                part_dict["stock_code"] = \
                    StockItem.objects.get(
                        stock_code=part.stock_code
                    ).stock_code
            except Exception:
                part_dict["stock_code"] = ""

            try:
                part_dict["stock_code"] = \
                    StockItem.objects.get(
                        stock_code=part.stock_code
                    ).stock_code
            except Exception:
                part_dict["stock_code"] = ""

            # children
            part_dict["child"] = {} 

            try:
                ## get parent stock code
                stock_item_parent = StockItem.objects.get(
                    stock_code=part.stock_code
                )
                print(stock_item_parent)
                stock_item_children = stock_item_parent.children
                child_stock_dict = {
                    s.sequence: s
                    for s in stock_item_children
                }

                for stock_sequence in child_stock_dict:
                    for child_part in part.children:
                        if child_part.sequence == stock_sequence:
                            part_dict["child"][
                                    stock_sequence
                                ] = {
                                    "sequence": stock_sequence,
                                    "serial_no": child_part.serial_no,
                                    "stock_code": child_part.stock_code,
                                    "car": child_part.car,
                                    "sw_ver": child_part.sw_ver,
                                    "hw_ver": child_part.hw_ver,
                                    "id": child_part.id,                            
                                    "last_status" : child_part.last_status,
                                    "description" : child_part.description
                                }
                            continue

                        else:
                            s = StockItem.objects.get(
                            pk=child_stock_dict[stock_sequence].child.id
                        )
                        part_dict["child"][
                                stock_sequence
                            ] = {
                                "sequence": stock_sequence,
                                "stock_code": s.stock_code,
                                "serial_no": "",
                                "car": "",
                                "description":s.description
                            }
                        
                    if not part.children:
                        s = StockItem.objects.get(
                                pk=child_stock_dict[stock_sequence].child.id
                            )
                        part_dict["child"][
                                    stock_sequence
                                ] = {
                                    "sequence": stock_sequence,
                                    "stock_code": s.stock_code,
                                    "serial_no": "",
                                    "car": "",
                                    "description":s.description
                                }

            # children
            #part_dict["child"] = {}
            #child_part_dict = {
            #    p.stock_code: p
            #    for p in part.children
            #}
            #try:
            #    stock_item_parent = StockItem.objects.get(
            #        stock_code=part.stock_code
            #    )

            #    stock_item_children = stock_item_parent.children
            #    for stock_item_child in stock_item_children:
            #        try:
            #            # part_child = Parts.objects.get(
            #            #     stock_code=stock_item_child.child.stock_code
            #            # )
            #            part_child = child_part_dict.get(
            #                stock_item_child.child.sequence
            #            )

            #            if part_child.parent_part.stock_code \
            #                    == stock_item_parent.stock_code:

            #                part_dict["child"][
            #                    part_child.stock_code
            #                ] = {
            #                    "sequence": part_child.sequence,
            #                    "serial_no": part_child.serial_no,
            #                    "car": part_child.car,
            #                    "sw_ver": part_child.sw_ver,
            #                    "hw_ver": part_child.hw_ver,
            #                    "id":part_child.id,
            #                    "description":part_child.description

            #                }
            #            else:
            #                part_dict["child"][
            #                    stock_item_child.child.stock_code
            #                ] = {
            #                    "sequence": stock_item_child.sequence,
            #                    "serial_no": "",
            #                    "car": "",
            #                    "description":stock_item_child.child.description

            #                }
            #        except Exception:
            #            part_dict["child"][
            #                stock_item_child.child.stock_code
            #            ] = {
            #                "sequence": stock_item_child.sequence,
            #                "serial_no": "",
            #                "car": "",
            #                "description":stock_item_child.child.description
            #            }

            except Exception as ex:
                print(ex)
            
            result.append(part_dict)

    return result


def fitment(parent_stock_code, parent_serial_no, new_car, username):
    '''
    Update car field.
    '''
    # try:
    update_list = []
    parent_part_queryset = Parts.objects.filter(
            stock_code=parent_stock_code,
            serial_no=parent_serial_no
        )
    count = parent_part_queryset.count()
    if count == 0:
        raise ValueError(f"The serial_no does not exist")
    elif count != 1:
        raise ValueError(f"The are two identical serial_no.")
    parent_part = parent_part_queryset.first()
    if Parts.objects.filter(stock_code=parent_stock_code,serial_no=parent_serial_no, deleted=False, last_check_out=None).exists():
        raise ValueError(f"{parent_part.description}, {parent_part.serial_no} has not check out")

    # if RepairOrderPart.objects.filter(stock_code=parent_stock_code,serial_no=parent_serial_no, deleted=False, last_check_out=None).exists():
    #     logging.warning("此订单有存在老的维修单零件没进行chekcout")

    payload = {
        "origin": parent_part.car,
        "new": new_car
    }

    parent_part.car = new_car
    # parent_part.location = new_car
    update_list.append(parent_part)

    actionType = Log.ActionType.FITMENT
    if new_car == '':
        action = 'defit from'
        location = payload["origin"]
        actionType = Log.ActionType.DEFITMENT
    else:
        action = 'fit to '
        location = payload["new"]

    new_log = Log(
            username=username,
            log_type=Log.LogType.DEPOT,
            category_type=Log.CategoryType.LOCATION,
            action_type=actionType,
            action='deport__fitment',
            payload= json.dumps(payload),
            description=f"SC: {parent_part.stock_code}, SN: {parent_part.serial_no} {action} location: {location}",
            repair_order=0,
            parent_stock_code=parent_part.stock_code,
            parent_part=parent_part.serial_no,
            part='',
            stock_code=''
        )
    new_log.save()
    
    for child in parent_part.children:
        child.car = new_car
        # child.location = new_car
        update_list.append(child)
        child_log = Log(
            username=username,
            log_type=Log.LogType.DEPOT,
            category_type=Log.CategoryType.LOCATION,
            action_type=Log.ActionType.FITMENT,
            action='deport__fitment',
            payload= json.dumps(payload),
            description=f"SC: {child.stock_code}, SN: {child.serial_no} {action} location: {location}",
            repair_order=0,
            parent_stock_code=parent_part.stock_code,
            parent_part=parent_part.serial_no,
            part=child.serial_no,
            stock_code=child.stock_code
        )
        child_log.save()

    with transaction.atomic():
        Parts.objects.bulk_update(update_list, ("car",))

    # except Exception:
    #     return False

    return True

